package com.digua.atools.tools;

import android.text.TextUtils;
import android.util.Log;

/**
 * @author:digua
 * @dat:2021/8/31
 * @description:Log工具类
 */
public class LogUtil {
    private static String customTagPrefix = "";

    private LogUtil() {
    }

    public static final boolean isPring = com.digua.atools.tools.AConfig.isDebug;
    public static boolean allowD = isPring;
    public static boolean allowE = isPring;
    public static boolean allowI = isPring;
    public static boolean allowV = isPring;
    public static boolean allowW = isPring;
    public static boolean allowWtf = isPring;
    public static boolean allowJson = isPring;

    public static String generateTag(StackTraceElement caller) {
        String tag = "%s.%s(L:%d)";
        String callerClazzName = caller.getClassName();
        callerClazzName = callerClazzName.substring(callerClazzName.lastIndexOf(".") + 1);
        tag = String.format(tag, callerClazzName, caller.getMethodName(), caller.getLineNumber());
        tag = TextUtils.isEmpty(customTagPrefix) ? tag : customTagPrefix + ":" + tag;
        return tag;
    }

    public static String generateTag() {
        StackTraceElement caller = getCallerStackTraceElement();
        String tag = "%s.%s(L:%d)";
        String callerClazzName = caller.getClassName();
        callerClazzName = callerClazzName.substring(callerClazzName.lastIndexOf(".") + 1);
        tag = String.format(tag, callerClazzName, caller.getMethodName(), caller.getLineNumber());
        tag = TextUtils.isEmpty(customTagPrefix) ? tag : customTagPrefix + ":" + tag;
        return tag;
    }

    public static CustomLogger customLogger;

    public interface CustomLogger {
        void d(String tag, String content);

        void d(String tag, String content, Throwable tr);

        void e(String tag, String content);

        void e(String tag, String content, Throwable tr);

        void i(String tag, String content);

        void i(String tag, String content, Throwable tr);

        void v(String tag, String content);

        void v(String tag, String content, Throwable tr);

        void w(String tag, String content);

        void w(String tag, String content, Throwable tr);

        void w(String tag, Throwable tr);

        void wtf(String tag, String content);

        void wtf(String tag, String content, Throwable tr);

        void wtf(String tag, Throwable tr);
    }

    public static void d(Object txt) {
        String content = txt + "";
        if (!allowD) {
            return;
        }
        StackTraceElement caller = getCallerStackTraceElement();
        String tag = generateTag(caller);

        if (customLogger != null) {
            customLogger.d(tag, content);
        } else {
            Log.d(tag, content);
        }
    }

    public static void ds(Object txt) {
        String content = txt + "";
        if (!allowD) {
            return;
        }
        StackTraceElement caller = getCallerStackTraceElement();
        String tag = generateTag(caller);
        int start = 0, end = 2000;
        String temp = "";
        while (content.length() > start) {
            end = content.length() > (end + 2000) ? (end + 2000) : content.length();
            temp = content.substring(start, end);
            if (customLogger != null) {
                customLogger.d(tag, temp);
            } else {
                Log.d(tag, temp);
            }
            start = end;
        }
    }

    public static void d(Object txt, Throwable tr) {
        String content = txt + "";
        if (!allowD) {
            return;
        }
        StackTraceElement caller = getCallerStackTraceElement();
        String tag = generateTag(caller);

        if (customLogger != null) {
            customLogger.d(tag, content, tr);
        } else {
            Log.d(tag, content, tr);
        }
    }

    public static void e(Object txt) {
        String content = txt + "";
        if (!allowE) {
            return;
        }
        StackTraceElement caller = getCallerStackTraceElement();
        String tag = generateTag(caller);

        if (customLogger != null) {
            customLogger.e(tag, content);
        } else {
            Log.e(tag, content);
        }
    }

    public static void e(String format, Object... param) {
        String content = com.digua.atools.tools.StrUtil.format(format, param);
        if (!allowE) {
            return;
        }
        StackTraceElement caller = getCallerStackTraceElement();
        String tag = generateTag(caller);
        if (customLogger != null) {
            customLogger.e(tag, content);
        } else {
            Log.e(tag, content);
        }
    }


    public static void es(Object txt) {
        String content = txt + "";
        if (!allowE) {
            return;
        }
        StackTraceElement caller = getCallerStackTraceElement();
        String tag = generateTag(caller);
        int start = 0, end = 2000;
        String temp = "";
        while (content.length() > start) {
            end = content.length() > (end + 2000) ? (end + 2000) : content.length();
            temp = content.substring(start, end);
            if (customLogger != null) {
                customLogger.e(tag, temp);
            } else {
                Log.e(tag, temp);
            }
            start = end;
        }
    }

    public static void e(Object txt, Throwable tr) {
        String content = txt + "";
        if (!allowE) {
            return;
        }
        StackTraceElement caller = getCallerStackTraceElement();
        String tag = generateTag(caller);

        if (customLogger != null) {
            customLogger.e(tag, content, tr);
        } else {
            Log.e(tag, content, tr);
        }
    }

    public static void i(Object txt) {
        String content = txt + "";
        if (!allowI) {
            return;
        }
        StackTraceElement caller = getCallerStackTraceElement();
        String tag = generateTag(caller);

        if (customLogger != null) {
            customLogger.i(tag, content);
        } else {
            Log.i(tag, content);
        }
    }

    public static void is(Object txt) {
        String content = txt + "";
        if (!allowI) {
            return;
        }
        StackTraceElement caller = getCallerStackTraceElement();
        String tag = generateTag(caller);
        int start = 0, end = 2000;
        String temp = "";
        while (content.length() > start) {
            end = content.length() > (end + 2000) ? (end + 2000) : content.length();
            temp = content.substring(start, end);
            if (customLogger != null) {
                customLogger.i(tag, temp);
            } else {
                Log.i(tag, temp);
            }
            start = end;
        }
    }

    public static void i(Object txt, Throwable tr) {
        String content = txt + "";
        if (!allowI) {
            return;
        }
        StackTraceElement caller = getCallerStackTraceElement();
        String tag = generateTag(caller);

        if (customLogger != null) {
            customLogger.i(tag, content, tr);
        } else {
            Log.i(tag, content, tr);
        }
    }

    public static void v(Object txt) {
        String content = txt + "";
        if (!allowV) {
            return;
        }
        StackTraceElement caller = getCallerStackTraceElement();
        String tag = generateTag(caller);

        if (customLogger != null) {
            customLogger.v(tag, content);
        } else {
            Log.v(tag, content);
        }
    }

    public static void vs(Object txt) {
        String content = txt + "";
        if (!allowV) {
            return;
        }
        StackTraceElement caller = getCallerStackTraceElement();
        String tag = generateTag(caller);
        int start = 0, end = 2000;
        String temp = "";
        while (content.length() > start) {
            end = content.length() > (end + 2000) ? (end + 2000) : content.length();
            temp = content.substring(start, end);
            if (customLogger != null) {
                customLogger.v(tag, temp);
            } else {
                Log.v(tag, temp);
            }
            start = end;
        }
    }

    public static void v(Object txt, Throwable tr) {
        String content = txt + "";
        if (!allowV) {
            return;
        }
        StackTraceElement caller = getCallerStackTraceElement();
        String tag = generateTag(caller);

        if (customLogger != null) {
            customLogger.v(tag, content, tr);
        } else {
            Log.v(tag, content, tr);
        }
    }

    public static void w(Object txt) {
        String content = txt + "";
        if (!allowW) {
            return;
        }
        StackTraceElement caller = getCallerStackTraceElement();
        String tag = generateTag(caller);

        if (customLogger != null) {
            customLogger.w(tag, content);
        } else {
            Log.w(tag, content);
        }
    }

    public static void ws(Object txt) {
        String content = txt + "";
        if (!allowW) {
            return;
        }
        StackTraceElement caller = getCallerStackTraceElement();
        String tag = generateTag(caller);
        int start = 0, end = 2000;
        String temp = "";
        while (content.length() > start) {
            end = content.length() > (end + 2000) ? (end + 2000) : content.length();
            temp = content.substring(start, end);
            if (customLogger != null) {
                customLogger.w(tag, temp);
            } else {
                Log.w(tag, temp);
            }
            start = end;
        }
    }

    public synchronized static void w(Object txt, Throwable tr) {
        String content = txt + "";
        if (!allowW) {
            return;
        }
        StackTraceElement caller = getCallerStackTraceElement();
        String tag = generateTag(caller);
        if (customLogger != null) {
            customLogger.w(tag, content, tr);
        } else {
            Log.w(tag, content, tr);
        }
    }

    public static void w(Throwable tr) {
        if (!allowW) {
            return;
        }
        StackTraceElement caller = getCallerStackTraceElement();
        String tag = generateTag(caller);

        if (customLogger != null) {
            customLogger.w(tag, tr);
        } else {
            Log.w(tag, tr);
        }
    }

    public static void wtf(Object txt) {
        String content = txt + "";
        if (!allowWtf) {
            return;
        }
        StackTraceElement caller = getCallerStackTraceElement();
        String tag = generateTag(caller);

        if (customLogger != null) {
            customLogger.wtf(tag, content);
        } else {
            Log.wtf(tag, content);
        }
    }

    public static void wtfs(Object txt) {
        String content = txt + "";
        if (!allowWtf) {
            return;
        }
        StackTraceElement caller = getCallerStackTraceElement();
        String tag = generateTag(caller);
        int start = 0, end = 2000;
        String temp = "";
        while (content.length() > start) {
            end = content.length() > (end + 2000) ? (end + 2000) : content.length();
            temp = content.substring(start, end);
            if (customLogger != null) {
                customLogger.wtf(tag, temp);
            } else {
                Log.wtf(tag, temp);
            }
            start = end;
        }
    }

    public static void wtf(Object txt, Throwable tr) {
        String content = txt + "";
        if (!allowWtf) {
            return;
        }
        StackTraceElement caller = getCallerStackTraceElement();
        String tag = generateTag(caller);

        if (customLogger != null) {
            customLogger.wtf(tag, content, tr);
        } else {
            Log.wtf(tag, content, tr);
        }
    }

    public static void wtf(Throwable tr) {
        if (!allowWtf) {
            return;
        }
        StackTraceElement caller = getCallerStackTraceElement();
        String tag = generateTag(caller);
        if (customLogger != null) {
            customLogger.wtf(tag, tr);
        } else {
            Log.wtf(tag, tr);
        }
    }

    public static StackTraceElement getCallerStackTraceElement() {
        return Thread.currentThread().getStackTrace()[4];
    }

}
